package com.hxh.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.plugins.Page;
import com.hxh.entity.Project;
import com.hxh.entity.ProjectDetail;
import com.hxh.entity.input.ProjectInput;
import com.hxh.entity.output.ApiResult;
import com.hxh.generater.common.GenSysMenu;
import com.hxh.generater.common.TreeBuilder;
import com.hxh.generater.springBoot.GenerationSpringBootAdapter;
import com.hxh.generater.vue.GenerationVueAdapter;
import com.hxh.service.ProjectDetailService;
import com.hxh.service.ProjectService;
import com.hxh.util.GenUtil;
import com.hxh.util.MysqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api/project")
@Slf4j
public class ProjectController {
    @Autowired
    ProjectService projectService;

    @Autowired
    ProjectDetailService projectDetailService;

    @Autowired
    GenerationVueAdapter generationVueAdapter;

    @Autowired
    GenerationSpringBootAdapter generationSpringBootAdapter;

    //获取项目配置分页
    @RequestMapping(value = "/listPage", produces = "application/json;charset=utf-8")
    public ApiResult listPage(ProjectInput pojo) {
        Page<Project> page = new Page<>(pojo.getCurrent(), pojo.getPageSize());
        projectService.listPage(page, pojo);
        return ApiResult.ok("获取项目配置分页成功", page);
    }

    @RequestMapping(value = "/getAllProjectOption", produces = "application/json;charset=utf-8")
    public ApiResult getAllProjectOption() {
        return ApiResult.ok("获取项目成功", projectService.select(new ProjectInput()));
    }

    //新增项目配置
    @PostMapping(value = "add")
    public ApiResult add(@RequestParam String project, @RequestParam String backendProject,
                         @RequestParam String frontendProject) {
        try {
            Project projectObject = JSONUtil.toBean(project, Project.class);
            ProjectDetail backendProjectObject = JSONUtil.toBean(backendProject, ProjectDetail.class);
            ProjectDetail frontendProjectObject = JSONUtil.toBean(frontendProject, ProjectDetail.class);
            boolean flag = projectService.insertAll(projectObject, backendProjectObject, frontendProjectObject);
            if (flag) {
                return ApiResult.ok("保存成功");
            }
            return ApiResult.fail("保存失败");
        } catch (Exception e) {
            log.error("保存项目配置失败", e);
            return ApiResult.fail("保存失败");
        }
    }

    //修改项目配置
    @PostMapping(value = "update")
    public ApiResult update(@RequestParam String project, @RequestParam String backendProject,
                            @RequestParam String frontendProject) {
        try {
            Project projectObject = JSONUtil.toBean(project, Project.class);
            ProjectDetail backendProjectObject = JSONUtil.toBean(backendProject, ProjectDetail.class);
            ProjectDetail frontendProjectObject = JSONUtil.toBean(frontendProject, ProjectDetail.class);
            boolean flag = projectService.updateAll(projectObject, backendProjectObject, frontendProjectObject);
            if (flag) {
                return ApiResult.ok("更新成功");
            }
            return ApiResult.fail("更新失败");
        } catch (Exception e) {
            log.error("更新项目配置失败", e);
            return ApiResult.fail("更新失败");
        }
    }

    //删除项目配置
    @PostMapping(value = "delete")
    public ApiResult deleteById(@RequestParam Integer id) {
        try {
            projectService.deleteAll(id);
            return ApiResult.ok("删除成功");
        } catch (Exception e) {
            log.error("删除项目配置失败", e);
            return ApiResult.fail("删除失败");
        }
    }

    /**
     * 初始化项目
     *
     * @param id              项目id
     * @param type            backendProject | frontendProject
     * @param initExtendTable 是否初始化数据库中用户添加的表
     * @return
     */
    @PostMapping(value = "initAllProject")
    public ApiResult initAllProject(@RequestParam Integer id, @RequestParam String type,
                                    @RequestParam Boolean initExtendTable) {

        try {
            Project project = projectService.selectById(id);
            if (project == null) {
                return ApiResult.fail("项目不存在！");
            }
            if (type.contains("backendProject")) {
                generationSpringBootAdapter.initProject(project, initExtendTable);
            }
            if (type.contains("frontendProject")) {
                //vue项目初始化
                generationVueAdapter.initProject(project, initExtendTable);
            }

            return ApiResult.ok("初始化项目成功");
        } catch (Exception e) {
            log.error("初始化项目失败", e);
            return ApiResult.fail("初始化项目失败");
        }
    }

    @PostMapping(value = "getSpringBootProjectMenu")
    public ApiResult getSpringBootProjectMenu(@RequestParam Integer id) {
        Project project = projectService.selectById(id);
        if (project == null) {
            return ApiResult.fail("项目不存在！");
        }
        try {
            List<GenSysMenu> list = MysqlUtils.executeOneQuery(project.getProjectDatasource(),
                    "select * from sys_menu order by sort;", GenSysMenu.class);
            return ApiResult.ok("获取菜单成功", TreeBuilder.buildTree(list));
        } catch (Exception e) {
            log.error("获取菜单失败", e);
            return ApiResult.fail("获取菜单失败");
        }
    }

    //删除菜单
    @PostMapping(value = "deleteSpringBootProjectMenu")
    public ApiResult deleteSpringBootProjectMenu(@RequestParam Integer projectId, @RequestParam String menuId) {
        try {
            Project project = projectService.selectById(projectId);
            if (project == null) {
                return ApiResult.fail("项目不存在！");
            }
            String sql = "DELETE FROM `sys_menu` where `id` = " + menuId + " " +
                    " or CONCAT (',',tree_path,',') LIKE CONCAT('%,'," + menuId + ",',%')";
            MysqlUtils.executeOneSql(project.getProjectDatasource(), sql);
            return ApiResult.ok("ok");
        } catch (Exception e) {
            return ApiResult.fail("删除失败" + e.getMessage());
        }
    }

    @PostMapping(value = "updateSpringBootProjectMenu")
    public ApiResult updateSpringBootProjectMenu(Integer projectId, GenSysMenu sysMenu) {
        try {
            Project project = projectService.selectById(projectId);
            if (project == null) {
                return ApiResult.fail("项目不存在！");
            }
            String sql = MysqlUtils.genUpdateSql(sysMenu, "sys_menu", "id");
            MysqlUtils.executeOneSql(project.getProjectDatasource(), sql);
            return ApiResult.ok("ok");
        } catch (Exception e) {
            return ApiResult.fail("更新失败" + e.getMessage());
        }
    }

    @PostMapping(value = "addSpringBootProjectMenu")
    public ApiResult addSpringBootProjectMenu(Integer projectId, GenSysMenu sysMenu) {
        try {
            Project project = projectService.selectById(projectId);
            if (project == null) {
                return ApiResult.fail("项目不存在！");
            }
            String sql = MysqlUtils.genInsertSql(sysMenu, "sys_menu");
            MysqlUtils.executeOneSql(project.getProjectDatasource(), sql);
            return ApiResult.ok("ok");
        } catch (Exception e) {
            return ApiResult.fail("保存失败" + e.getMessage());
        }
    }


    @PostMapping(value = "clearAllBakFile")
    public ApiResult clearAllBakFile(Integer backendProjectId, Integer frontendProjectId) {
        try {
            if (backendProjectId != null) {
                ProjectDetail projectDetail = projectDetailService.selectById(backendProjectId);
                if (projectDetail == null) {
                    return ApiResult.fail("项目不存在！");
                }
                GenUtil.clearAllBakFile(projectDetail.getProjectDir() + projectDetail.getProjectName());
            }
            if (frontendProjectId != null) {
                ProjectDetail projectDetail = projectDetailService.selectById(frontendProjectId);
                if (projectDetail == null) {
                    return ApiResult.fail("项目不存在！");
                }
                GenUtil.clearAllBakFile(projectDetail.getProjectDir() + projectDetail.getProjectName());
            }
            return ApiResult.ok("删除bak文件成功");
        } catch (Exception e) {
            log.error("删除bak文件失败", e);
            return ApiResult.fail("删除bak文件失败");
        }
    }

}
